package com.stu.service.base.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.HibernateException;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;

import com.stu.dao.base.IBaseDao;
import com.stu.dao.sys.ISysLogDao;
import com.stu.entity.base.BaseEntity;
import com.stu.entity.service.News;
import com.stu.entity.sys.ISysLog;
import com.stu.service.base.IBaseService;
import com.stu.utils.BeanUtils;
import com.stu.utils.JedisUtils;
import com.stu.utils.ListTranscoder;
import com.stu.utils.ObjectsTranscoder;
import com.stu.utils.RedisClient;

/**
 * service 基类
 * @author lijian
 *
 * @param <T> PO
 */
@Service
public class BaseService<T extends BaseEntity> implements IBaseService<T>,ISysLog{
	
	@Resource
	protected IBaseDao<T> baseDao;
	@Resource
	protected ISysLogDao sysLogDao;
	
//	protected Jedis jedis = new Jedis("127.0.0.1",6379);
	protected JedisUtils<T> jedisUtils=new JedisUtils<T>();
	protected RedisClient redisClient=RedisClient. getInstance();
	protected ObjectsTranscoder<T> objTranscoder =  new ObjectsTranscoder<T>();
	protected ListTranscoder<T> listTranscoder = new ListTranscoder<T>();
	
	

	@Override
	public Serializable save(T o) throws SQLException {
		if (StringUtils.isEmpty(o.getUuid())){
			o.setUuid(UUID.randomUUID().toString().replaceAll("-", "").toLowerCase());
		}
		o.setCreateTime(new Date());
		return baseDao.save(o);
	}
	
	@Override
	public void saveBatch(List<? extends BaseEntity> list) throws SQLException {
		baseDao.saveBatch(list);
	}	

	@Override
	public boolean delete(T o) {
		if(!StringUtils.isEmpty(o.getUuid())){
			try {
				baseDao.delete(o);
				return true;
			} catch (Exception e) {
				return false;
			}
		}else{
			return false;
		}
	}
	

	@Override
	public boolean deleteIds(String ids) throws SQLException  {
		String[] uuid = ids.split(",");
		for (int i = 0; i < uuid.length; i++) {
			if(StringUtils.isNotBlank(uuid[i])){
				this.delete(this.findById(uuid[i]));
			}
		}
		return true;
	}
	

	@Override
	public boolean update(T o) throws SQLException {
		return this.update(o, null);
	}
	@Override
	public boolean update(T o, List<String> except) throws SQLException  {
		
		if (except == null) {
			except = new ArrayList<String>();
		}
		if (!StringUtils.isBlank(o.getUuid().toString())) {
			T t = this.findById(o.getUuid());
			BeanUtils.copyNotNullProperties(o, t, except.toArray(new String[except.size()]));
			return true;
		} else {
			return false;
		}
	}

	@Override
	public T findById(String id) throws SQLException {
		Class<?> c = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		return this.findById(c, id);
	}
	
	@Override
	public T findById(Class<?> c, Serializable id) throws SQLException {
		return baseDao.findById(c, id);
	}
	@Override
	public T findByHql(String hql) throws HibernateException, SQLException {
		return this.findByHql(hql, null);
	}
	@Override
	public T findByHql(String hql, Map<String, Object> params) throws HibernateException, SQLException {
		return baseDao.getByHql(hql, params);
	}
	@Override
	public List<T> find() throws SQLException  {
		String className = ((Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getName();
		String hql = "select distinct t from " + className + " t ";
		return this.find(hql, null,0,0);
	}

	@Override
	public List<T> find(String hql) throws SQLException  {
		return this.find(hql, null, 0, 0);
	}
	@Override
	public List<T> find(String hql, Map<String, Object> params) throws SQLException {
		return this.find(hql, params, 0, 0);
	}
	
	@Override
	public List<T> find(int page, int rows) throws SQLException  {
		String className = ((Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getName();
		String hql = "from " + className + " t ";
		return this.find(hql, null, page, rows);
	}
	
	@Override
	public List<T> find(String hql, Map<String, Object> params, int page, int rows) throws SQLException  {
		return baseDao.findByHql(hql, params, page, rows);
	}
	
	@Override
	public List<Map<String, ?>> findBySqlToMap(String sql) throws HibernateException, SQLException {
		return this.findBySqlToMap(sql, null, 0, 0);
	}

	@Override
	public List<Map<String, ?>> findBySqlToMap(String sql, int page, int rows) throws HibernateException, SQLException {
		return this.findBySqlToMap(sql,null, page, rows);
	}

	@Override
	public List<Map<String, ?>> findBySqlToMap(String sql, Map<String, Object> params) throws HibernateException, SQLException {
		return this.findBySqlToMap(sql, params,0,0);
	}

	@Override
	public List<Map<String, ?>> findBySqlToMap(String sql, Map<String, Object> params, int page, int rows) throws HibernateException, SQLException {
		return baseDao.findBySqlToMap(sql, params, page, rows);
	}

	@Override
	public int count() throws SQLException  {
		String className = ((Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getName();
		String hql = "select count(distinct t) from " + className + " t ";
		return this.count(hql);
	}

	@Override
	public int count(String hql) throws SQLException  {
		return baseDao.getCountByHql(hql);
	}
	@Override
	public int count(String hql, Map<String, Object> params) throws SQLException  {
		return baseDao.getCountByHql(hql, params);
	}

	@Override
	public int countBySql(String sql) throws SQLException  {
		return baseDao.getCountBySql(sql);
	}
	
	@Override
	public int executeSql(String sql) throws SQLException {
		return this.executeSql(sql,null);
	}

	@Override
	public int executeSql(String sql, Map<String, Object> params) throws SQLException  {
		return baseDao.executeSql(sql, params);
	}

	@Override
	public int executeHql(String hql, Map<String, Object> params) throws SQLException  {
		return baseDao.executeHql(hql,params);
	}
	@Override
	public int executeHql(String hql) throws SQLException  {
		return this.executeHql(hql,null);
	}

	@Override
	public List<T> findBySqlToBean(String sql, Map<String, Object> params, int page, int rows, Class<T> clazz)
			throws HibernateException, SQLException {
		return baseDao.findToBean(sql, params, page, rows, clazz);
	}

	@Override
	public List<T> findBySqlToBean(String sql, Map<String, Object> params, int page, int rows)
			throws HibernateException, SQLException {
		ParameterizedType pt=(ParameterizedType)this.getClass().getGenericSuperclass();
		Class<T>clazz=(Class<T>)pt.getActualTypeArguments()[0];
		return this.findBySqlToBean(sql, params, page, rows, clazz);
	}

	
}
